/**
 * Created by jinxs on 2014.12.24.
 */
(function ($) {
    /**
     * 缓存名称
     * @type {string}
     * @private
     */
    var _cacheName = 'uiWizard';
    /**
     * @name uiWizard
     * @class 向导组件
     * @constructor
     * @summary 构造函数
     * @param {Object|String} options 如果为Object，则表示组件配置，如果为String，则调用组件方法
     * @param {Object} param 当options为String时，可以传入方法参数
     * @returns {jQuery} jQuery对象
     * @example
     *  //采用默认值
     * $('#ul').uiWizard();
     * //设置组件参数
     *  $('#ul').uiWizard({selectedItem: {step:1}});
     * //调用组件方法
     * $('#ul').uiWizard('options');
     */
    $.fn.uiWizard = function (options, param) {
        if (typeof options == 'string') {
            return $.fn.uiWizard.methods[options](this, param);
        }
        return this.each(function(){
            var me = $(this);
            var state = me.data(_cacheName);

            options = options || {};
            if (state) {
                $.extend(state.options, options);
            } else {
                me.data(_cacheName, {
                    options: $.extend({}, $.fn.uiWizard.defaults, me.parseUIConfig(), options)
                });
            }
            _init(me);
        });
    };
    /**
     * 方法
     * @lends uiWizard.prototype
     */
    $.fn.uiWizard.methods = {
        /**
         * @summary 获取组件配置参数
         * @function
         * @name uiWizard#options
         * @returns {Object}
         * @example
         *  $('#ul').uiWizard('options');
         */
        options: function (target) {
            return $.data(target[0], _cacheName).options;
        },
        /**
         * @summary 到上一步
         * @function
         * @name uiWizard#previous
         * @returns {Object}
         * @example
         *  $('#ul').uiWizard('previous');
         */
        previous: function (target) {
            _previous(target);
        },
        /**
         * @summary 到下一步
         * @function
         * @name uiWizard#next
         * @returns {Object}
         * @example
         *  $('#ul').uiWizard('next');
         */
        next: function (target) {
            _next(target);
        },
        /**
         * @summary 转到指定步骤
         * @function
         * @name uiWizard#selectedItem
         * @returns {Object}
         * @example
         * //获取当前步骤 ，返回值{step:xx}
         *  $('#ul').uiWizard('selectedItem');
         *  //转到指定步骤1
         *  $('#ul').uiWizard('selectedItem',{step:1});
         */
        selectedItem: function (target, selectedItem) {
            return _selectedItem(target, selectedItem);
        }
    };
    /**
     * 默认配置
     * @lends uiWizard.prototype
     */
    $.fn.uiWizard.defaults =
    {
        /**
         * @summary 选中的步骤
         * @type String
         * @default ""
         */
        selectedItem: {step: 1},
        /**
         * @summary 上一步按钮
         * @type Jquery对象
         * @default null
         */
        buttonPrev: null,
        /**
         * @summary 下一步按钮
         * @type Jquery对象
         * @default null
         */
        buttonNext: null,
        /**
         * @summary 不允许返回上一步
         * @type boolean
         * @default false
         */
        disablePreviousStep: false,
        /**
         * @summary 最后一步显示文字
         * @type String
         * @default 完成
         */
        lastText: '完成',
        /**
         * @summary 在步骤改变前触发。
         * @event
         * @name uiWizard#onBeforeStepChange
         * @param currStep {Int} 当前所在步骤
         * * @param type {Int} 触发来源 -1：步骤点击 0：上一步 1:下一步
         * @this 组件jQuery对象
         * @default emptyFn
         */
        onBeforeStepChange: function (currStep,type) {
        },
        /**
         * @summary 在步骤改变后触发。
         * @event
         * @name uiWizard#onStepChanged
         * @param currStep {Int} 改变后所在步骤
         * @this 组件jQuery对象
         * @default emptyFn
         */
        onStepChanged: function (currStep) {
        }
        ,onFinished:function(){

        }
    };
//////--------------------------------内部方法------------------------------
    var _init = function (target) {
        var state = $.data(target[0], _cacheName);
        var options = state.options;
        target.addClass('ui_wizard');
        if (_IE8) {
            target.addClass('ui_wizard_IE8');
        }
        if (_IEunder8) {
            var children = target.children();
            children.css('width', Math.floor(90 / children.length) + '%');
        }
        options.currentStep = options.selectedItem.step;
        options.numSteps = target.find('> li').length;
        var prevBtn = options.buttonPrev;
        var nextBtn = options.buttonNext;
        options.nextText = nextBtn.uiButton('getLabel');

        prevBtn.on('click', function (e) {
                _previous(target);
            }
        );
        nextBtn.on('click', function (e) {
            _next(target);
        });
        target.on('click', 'li.complete', function (e) {
            _stepClicked(target, e);
        });

        if (options.currentStep > 1) {
            _selectedItem(target, options.selectedItem);
        } else {
            _setState(target);
        }

        if (options.disablePreviousStep) {
            prevBtn.uiButton('setDisabled', true);
            target.addClass('previous-disabled');
        }
        return target;
    };
    var _setState = function (target) {
        var state = $.data(target[0], _cacheName);
        var options = state.options;
        var canMovePrev = (options.currentStep > 1);
        var firstStep = (options.currentStep === 1);
        var lastStep = (options.currentStep === options.numSteps);

        var prevBtn = options.buttonPrev;
        var nextBtn = options.buttonNext;
        if (!options.disablePreviousStep) {
            prevBtn.uiButton('setDisabled', (firstStep === true || canMovePrev === false));
        }

        if (options.lastText !== '') {
            var text = (lastStep !== true) ? options.nextText : options.lastText;
            nextBtn.text(text);
        }

        var steps = target.find('> li');
        steps.removeClass('active').removeClass('complete').removeClass('completeIE8');

        var prevSelector = '> li:lt(' + (options.currentStep - 1) + ')';
        var prevSteps = target.find(prevSelector);
        prevSteps.addClass('complete');
        if (_IE8) {
            prevSteps.addClass('completeIE8');
        }

        var currentSelector = '> li:eq(' + (options.currentStep - 1) + ')';
        var currentStep = target.find(currentSelector);
        currentStep.addClass('active');
        options.onStepChanged.call(target, options.currentStep);
    };

    var _stepClicked = function (target, e) {
        var state = $.data(target[0], _cacheName);
        var options = state.options;
        var li = $(e.currentTarget);
        var index = target.find('>li').index(li);
        var canMovePrev = true;

        if (options.disablePreviousStep) {
            if (index < options.currentStep) {
                canMovePrev = false;
            }
        }

        if (canMovePrev) {
            if (options.onBeforeStepChange.call(target, options.currentStep,-1) == false) {
                return;
            }
            options.currentStep = (index + 1);
            _setState(target);
        }
    };
    var _previous = function (target) {
        var state = $.data(target[0], _cacheName);
        var options = state.options;
        var canMovePrev = (options.currentStep > 1);
        if (options.disablePreviousStep) {
            canMovePrev = false;
        }
        if (canMovePrev) {
            if (options.onBeforeStepChange.call(target, options.currentStep,0) == false) {
                return;
            }
            options.currentStep -= 1;
            _setState(target);
        }
    }
    var _next = function (target) {
        var state = $.data(target[0], _cacheName);
        var options = state.options;

        var canMoveNext = (options.currentStep + 1 <= options.numSteps);
        var lastStep = (options.currentStep === options.numSteps);

        if (canMoveNext) {
            if (options.onBeforeStepChange.call(target, options.currentStep,1) == false) {
                return;
            }
            options.currentStep += 1;
            _setState(target);
        }
        else if (lastStep) {
            options.onFinished.call(target);
        }
    };
    var _selectedItem = function (target, selectedItem) {
        var state = $.data(target[0], _cacheName);
        var options = state.options;
        var retVal, step;

        if (selectedItem) {

            step = selectedItem.step || -1;

            if (step >= 1 && step <= options.numSteps) {
                options.currentStep = step;
                _setState(target);
            }

            retVal = target;
        }
        else {
            retVal = {step: options.currentStep};
        }

        return retVal;
    }
})
(jQuery);